﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
using MsExcel = Microsoft.Office.Interop.Excel;

namespace FileSync
{
    public partial class Form1 : Form
    {
        private static Guid sourceReplicaID;
        private static Guid destinationReplicaID;
        private static bool is64BitAch = System.Environment.Is64BitOperatingSystem;
        private static string systemArchitecture = System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
        private static bool isMsSyncInstalled;
        private static string strAppBasePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\FileSync\\";
        private enum SyncWay
        {
            TwoWay,
            Source_To_Destination,
            Destination_To_Source,
        }
        public Form1()
        {
            InitializeComponent();
            this.textBox1.Text = strAppBasePath;
            func_PreReq_CreateExcelSheetIfAbsent(strAppBasePath);
            isMsSyncInstalled = func_PreReq_MsSyncFwInstalled();

            //this.toolTip1.SetToolTip(this.btOpenExcel, "Syncs directories on left with those on right in 2-way manner, any chage on any side would be synced on both sides");
            //this.toolTip2.SetToolTip(this.btLTR, "Syncs directories on the left with right, not vice-versa");
            //this.toolTip3.SetToolTip(this.btRTL, "Syncs directories on the right with left, not vice-versa");

            this.toolTip1.SetToolTip(this.btOpenExcel, "Opens the Excel file containg the mappings for file syncing");

            if (!isMsSyncInstalled)
            {
                this.label4.ForeColor = System.Drawing.Color.Red;
                this.label4.Text = "Restart after installing: Microsoft Sync f/w for";
                this.btSync.Enabled = false;
            }
            else
            {
                this.label4.ForeColor = System.Drawing.Color.Green;
                this.label4.Text = "Microsoft Sync f/w Installed for";
            }

            if (is64BitAch)
            {
                this.comboBox1.SelectedIndex = 1;
                this.comboBox1.Enabled = false;
            }
            else if (systemArchitecture.Equals("x86", StringComparison.CurrentCultureIgnoreCase))
            {
                this.comboBox1.SelectedIndex = 0;
                this.comboBox1.Enabled = false;
            }
            else if (systemArchitecture.Equals("IA64", StringComparison.CurrentCultureIgnoreCase))
            {
                this.comboBox1.SelectedIndex = 2;
                this.comboBox1.Enabled = false;
            }
            else
            { }
        }

        private void func_PreReq_CreateExcelSheetIfAbsent(string strAppBasePath)
        {
            string strWorkSheetFileName = "SyncSheet.xlsx";
            if (System.IO.File.Exists(strAppBasePath + strWorkSheetFileName))
                return;
            else
            {
                MsExcel.Application ExcelApp;
                MsExcel.Workbook ExcelWorkBook;
                MsExcel.Worksheet ExcelWorkSheet;
                MsExcel.Range ExcelCellRange;
                Object missingValue = System.Reflection.Missing.Value;

                ExcelApp = new MsExcel.Application();
                if (ExcelApp != null)
                {
                    ExcelApp.Visible = true;
                    ExcelWorkBook = ExcelApp.Workbooks.Add(MsExcel.XlWBATemplate.xlWBATWorksheet);

                    ExcelWorkSheet = (MsExcel.Worksheet)ExcelWorkBook.Worksheets[1];
                    ExcelWorkSheet.Cells[1, 1] = "WelCome To File Sync App";
                    ExcelWorkSheet.Cells[1, 3] = "Please clear all ...";
                    ExcelWorkSheet.Cells[3, 1] = "First Column";
                    ExcelWorkSheet.Cells[3, 2] = "Second Column";
                    ExcelWorkSheet.Cells[3, 3] = "Third Column";
                    ExcelWorkSheet.Cells[5, 1] = "source path";
                    ExcelWorkSheet.Cells[5, 2] = "target path";
                    ExcelWorkSheet.Cells[5, 3] = "sync mode (1/2/3)";
                    ExcelWorkSheet.Cells[6, 4] = "Mode 1 : Syncs directories on left with those on right in 2-way manner, any chage on any side would be synced on both sides";
                    ExcelWorkSheet.Cells[7, 4] = "Mode 2 : Syncs directories on the left with right, not vice-versa";
                    ExcelWorkSheet.Cells[8, 4] = "Mode 3 : Syncs directories on the right with left, not vice-versa";

                    ExcelCellRange = ExcelWorkSheet.get_Range("A1", "H10");
                    bool autofit = ExcelWorkSheet.Columns.AutoFit();
                    ExcelWorkBook.SaveAs(strAppBasePath + strWorkSheetFileName);
                    //ExcelWorkBook.Close(true, missingValue, missingValue);
                    //ExcelApp.Quit();
                }
            }
        }

        private bool func_PreReq_MsSyncFwInstalled()
        {
            IEnumerable<string> MsSyncFw;
            string regKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
            using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regKey))
            {
                MsSyncFw = from installedPrgoram in key.GetSubKeyNames()
                           where (
                                    key.OpenSubKey(installedPrgoram).GetValue("DisplayName") != null &&
                                    key.OpenSubKey(installedPrgoram).GetValue("DisplayName").ToString().Contains("Microsoft Sync Framework")
                                )
                           select key.OpenSubKey(installedPrgoram).GetValue("DisplayName").ToString();
                if (MsSyncFw.Count() > 0)
                    return true;
                else
                    return false;
            }
        }

        private void Synchronize(string strSourcePath, string strDestinationPath, SyncWay syncDirection = SyncWay.TwoWay)
        {
            sourceReplicaID = Guid.NewGuid();
            destinationReplicaID = Guid.NewGuid();
            FileSyncProvider sourceProvider = new FileSyncProvider(sourceReplicaID, strSourcePath);
            FileSyncProvider destinationProvider = new FileSyncProvider(destinationReplicaID, strDestinationPath);
            SyncOrchestrator syncAgent = new SyncOrchestrator();
            syncAgent.LocalProvider = sourceProvider;
            syncAgent.RemoteProvider = destinationProvider;
            syncAgent.Synchronize();
            Console.Write("Synchronization Complete.");
        }

        private void Sync_Click(object sender, EventArgs e)
        {
            IEnumerable<string> strSourceLocation = null, strTargetLocation = null;
            System.IO.FileInfo file = new System.IO.FileInfo(strAppBasePath + "File.txt");
            file.Directory.Create();
            if (System.IO.Directory.Exists(file.Directory.ToString()))
            {
                if (System.IO.File.Exists(file.FullName))
                {
                    var taskFile = System.IO.File.ReadAllLines(strAppBasePath + "File.txt");
                    List<string> taskList = new List<string>(taskFile);
                    string[] parms;
                    char[] delimiters = new char[] { ',' };
                    foreach (string task in taskList)
                    {
                        parms = task.Split(delimiters, 3);
                        if (parms.Length == 3)
                        {
                            Synchronize(parms[0], parms[1], (SyncWay)Convert.ToInt16(parms[3].ToString()));
                        }
                        else if (parms.Length == 2)
                        {
                            Synchronize(parms[0], parms[1]);
                        }
                    }
                }
                else
                {
                    using (System.IO.StreamWriter streamW = System.IO.File.CreateText(file.FullName))
                    {
                        streamW.Write("Target Directory Path1\nImage Directory Path1\nTarget Directory Path2\nImage Directory Path2\n\n\nClear All contents of this file and specify paths. All Paths of even lines are synced with file path specified on the odd line #.");
                    }
                }
            }

            if (strSourceLocation != null & strTargetLocation != null)
            {
                if (strSourceLocation.Count().Equals(strTargetLocation.Count()))
                {
                    for (int i = 0; i < strTargetLocation.Count(); i++)
                    {
                        Synchronize(strSourceLocation.Skip(i).FirstOrDefault(), strTargetLocation.Skip(i).FirstOrDefault());
                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.folderBrowserDialog1.ShowDialog();
            this.textBox1.Text = this.folderBrowserDialog1.SelectedPath;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            strAppBasePath = this.textBox1.Text;
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.notifyIcon1.Visible = true;
                this.ShowInTaskbar = false;
                this.notifyIcon1.BalloonTipTitle = "File Sync";
                this.notifyIcon1.BalloonTipText = "Application is still running";
                try
                {
                    this.notifyIcon1.ShowBalloonTip(500);
                    this.notifyIcon1.BalloonTipClicked += new EventHandler(notifyIcon1_BalloonTipClicked);
                }
                catch (Exception)
                {

                    throw;
                }
                this.Hide();
            }
            else if (this.WindowState == FormWindowState.Normal)
            {
                this.notifyIcon1.Visible = false;
            }
        }

        void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
            this.notifyIcon1.Visible = false;
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
        }

        private void btOpenExcel_Click(object sender, EventArgs e)
        {
            string strWorkSheetFileName = "SyncSheet.xlsx";
            if (System.IO.File.Exists(strAppBasePath + strWorkSheetFileName))
            {
                MsExcel.Application ExcelApp;
                MsExcel.Workbook ExcelWorkBook;
                MsExcel.Worksheet ExcelWorkSheet;
                MsExcel.Range ExcelCellRange;
                Object missingValue = System.Reflection.Missing.Value;

                ExcelApp = new MsExcel.Application();
                if (ExcelApp != null)
                {
                    ExcelApp.Visible = true;
                    //ExcelWorkBook = ExcelApp.Workbooks.Add(MsExcel.XlWBATemplate.xlWBATWorksheet);
                    ExcelWorkBook = ExcelApp.Workbooks.Open(strAppBasePath + strWorkSheetFileName,
                        missingValue, missingValue, missingValue, missingValue,
                        missingValue, missingValue, missingValue, missingValue,
                        missingValue, missingValue, missingValue, missingValue,
                        missingValue, missingValue);
                }
            }
        }
    }
}
